package com.oocl.im.clinet;

import java.awt.AWTException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

import javax.swing.DefaultListModel;

import com.oocl.im.gui.ChatFrame;
import com.oocl.im.gui.ErrorFrame;
import com.oocl.im.packet.MsgPackage;
import com.oocl.im.packet.Operation;

public class Client {
	private String sender;
	private String receiver;
	private Map<String, StringBuilder> chatHistory;
	private Map<String, Boolean> onlineInfo;
	private ChatFrame cf;

	private SimpleDateFormat sdf = new SimpleDateFormat("HH:ss");
	Socket socket;
	ObjectInputStream in;
	ObjectOutputStream out;

	public String getSender() {
		return sender;
	}

	public Map<String, Boolean> getOnlineInfo() {
		return onlineInfo;
	}

	public Client(String sender, ChatFrame cf) throws Exception {
		this.sender = sender;
		this.cf = cf;
		this.chatHistory = new HashMap<String, StringBuilder>();
		this.socket = new Socket("127.0.0.1", 8123);
		this.out = new ObjectOutputStream(socket.getOutputStream());
		this.in = new ObjectInputStream(socket.getInputStream());
		login();
	}

	public void login() throws Exception {
		MsgPackage msg = new MsgPackage(Operation.LOGIN, sender, null, null,
					new Date(), null);
		out.writeObject(msg);
		ReceiverThread receiverThread = new ReceiverThread(socket, in, out,
					this);
		setReceiver("all");
		new Thread(receiverThread).start();

	}

	public void setReceiver(String receiver) {
		this.receiver = receiver;
		StringBuilder chatHistory2 = null;
		if (chatHistory.containsKey(receiver)) {
			chatHistory2 = chatHistory.get(receiver);
		} else {
			chatHistory2 = new StringBuilder();
			chatHistory.put(receiver, chatHistory2);
		}

		cf.setTitle(sender, receiver);
		cf.setChatTa(chatHistory2.toString());
	}

	public void chat(String content) {
		Date date = new Date();
		MsgPackage msg = new MsgPackage(Operation.CHAT, sender, receiver,
				content, date, null);
		try {
			out.writeObject(msg);
			StringBuilder chatHistory2 = chatHistory.get(receiver);
			chatHistory2.append(sender + "\t" + sdf.format(msg.getDate())
					+ "\n" + content + "\n");
			cf.setChatTa(chatHistory2.toString());
		} catch (IOException e) {
			cf.exit("send erros");
			e.printStackTrace();
		}
	}

	public void shake() {
		MsgPackage msg = new MsgPackage(Operation.SHAKE, sender, receiver,
				null, new Date(), null);
		if(msg.getReceiver().equals("all")){
			cf.getChatTa().append("System hint: Can't shake all !!\n");
		}
		try {
			out.writeObject(msg);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void exit() {
		MsgPackage msg = new MsgPackage(Operation.EXIT, sender, null, null,
				new Date(), null);
		try {
			out.writeObject(msg);
			socket.close();

		} catch (IOException e) {
			//e.printStackTrace();
		}
	}

	public void notifyGui(MsgPackage msg) {
		onlineInfo = msg.getOnlineMap();
		cf.setFriendList(onlineInfo);
	}

	public void shakeGui(MsgPackage msg) {
		String sender = msg.getSender();
		setReceiver(sender);
		try {
			cf.shakeFrame1();
		} catch (AWTException e) {
			e.printStackTrace();
		}
	}

	public void chatGui(MsgPackage msg) {
		StringBuilder chatHistory2 = null;
		if (msg.getReceiver().equals("all")) {
			chatHistory2 = chatHistory.get("all");
			setReceiver("all");
		} else {
			if (chatHistory.containsKey(msg.getSender())) {
				chatHistory2 = chatHistory.get(msg.getSender());
			} else {
				chatHistory2 = new StringBuilder();
				chatHistory.put(msg.getSender(), chatHistory2);
			}
			setReceiver(msg.getSender());
		}
		chatHistory2.append(msg.getSender() + "\t" + sdf.format(msg.getDate())
				+ "\n" + msg.getContent() + "\n");
		cf.setChatTa(chatHistory2.toString());

	}

	public void exitGui(MsgPackage msg) {
		String exitMessage = msg.getContent();
		cf.exit(exitMessage);
	}

	public void exitGui(String msg) {
		cf.exit(msg);
	}

}
